import os
import tempfile
from typing import List, Dict

import pdfplumber
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.parsers import MultiPartParser, FormParser

from rag.emm.job_recommendation.job_recommendation import hybrid_search_jobs


def _extract_pdf_text(file_path: str) -> str:
    texts: List[str] = []
    with pdfplumber.open(file_path) as pdf:
        for page in pdf.pages:
            texts.append(page.extract_text() or "")
    return "\n".join(texts).strip()


def _generate_reasons_qwen(jobs: List[Dict], resume_text: str, model: str = "qwen-plus") -> List[str]:
    """
    使用通义兼容接口生成每个岗位的个性化推荐理由。
    依赖环境变量: DASHSCOPE_API_KEY
    """
    try:
        from openai import OpenAI
    except Exception as e:
        raise RuntimeError(f"openai SDK 未安装: {e}")

    api_key = os.getenv("DASHSCOPE_API_KEY")
    if not api_key:
        raise ValueError("请设置 DASHSCOPE_API_KEY 环境变量")

    client = OpenAI(api_key=api_key, base_url="https://dashscope.aliyuncs.com/compatible-mode/v1")
    reasons: List[str] = []
    
    # 提取简历关键信息（技能、经验、项目等）
    resume_summary = resume_text[:1200]  # 截断避免过长
    
    for j in jobs:
        title = j.get('title', '')
        company = j.get('company', '')
        city = j.get('city', '')
        tags = j.get('tags', '')
        desc = j.get('searchable_text', '')[:500] if j.get('searchable_text') else ''
        
        # 个性化提示词，针对具体岗位特点
        system_msg = f"""你是专业的岗位推荐顾问。基于简历内容与岗位信息，为每个岗位生成3-4条个性化推荐理由。
要求：
1. 每条理由20字以内，突出匹配度
2. 结合岗位具体技术栈、职责、公司特点
3. 体现简历与岗位的契合点
4. 避免模板化，要针对性强"""
        
        user_msg = f"""简历摘要：{resume_summary}

目标岗位：{title}
公司：{company} | 城市：{city}
技术标签：{tags}
岗位描述：{desc}

请基于以上信息，生成针对这个具体岗位的推荐理由："""
        
        msgs = [
            {"role": "system", "content": system_msg},
            {"role": "user", "content": user_msg}
        ]
        
        try:
            resp = client.chat.completions.create(
                model=model, 
                messages=msgs, 
                temperature=0.3, 
                max_tokens=300
            )
            reasons.append((resp.choices[0].message.content or "").strip())
        except Exception as e:
            # 降级到简单理由
            reasons.append(f"技术栈匹配度高，符合岗位要求")
    
    return reasons


class RecommendJobsView(APIView):
    parser_classes = (MultiPartParser, FormParser)

    def post(self, request):
        file_obj = request.FILES.get("file")
        if not file_obj:
            return Response({"detail": "缺少文件参数 file"}, status=status.HTTP_400_BAD_REQUEST)

        top_k = int(request.data.get("top_k", 8))

        # 保存临时文件并提取文本
        with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp:
            for chunk in file_obj.chunks():
                tmp.write(chunk)
            tmp_path = tmp.name

        try:
            resume_text = _extract_pdf_text(tmp_path)
            if not resume_text:
                return Response({"detail": "无法从PDF提取文本"}, status=status.HTTP_400_BAD_REQUEST)

            # 用简历文本作为查询进行混合检索
            items = hybrid_search_jobs(query=resume_text, top_k=top_k)

            # 生成推荐理由
            reasons = _generate_reasons_qwen(items, resume_text)
            for i, it in enumerate(items):
                it["reason"] = reasons[i]

            return Response({"items": items}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({"detail": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        finally:
            try:
                os.remove(tmp_path)
            except Exception:
                pass
